#ifndef __UDSF_DELAY_C__
#define __UDSF_DELAY_C__

#include "app.h"

/*
*   notice:
*   UDSF 同UDF编程：不可调用cstd-lib,只可调用"sdk_ifs_udk_cfg.h"、"sys_api.h"中列出的API函数。
*   UDSF文件内函数均需使用static修饰符，且UDF中以#include "udsf_xxx.c"形式引用
*/

static void udsf_delay_us_rom(int us_cnt) __attribute__((unused));
static void udsf_delay_ms_rom(int ms_cnt) __attribute__((unused));
static void udsf_delay_us_xip(int us_cnt) __attribute__((unused));
static void udsf_delay_ms_xip(int ms_cnt) __attribute__((unused));

/**
 * @Breif  : HW_Delay_us : delay n microsecodes use systick
 *
 * @Param  : u32Cnt: delay time, max value: 400000
 */
static void udsf_hw_delay_us(uint32_t u32Cnt)
{
	uint32_t hclk = 	XIP_SYS_CLK;

	if( p_rom_gb->boot_flag == ROM_STARTUP ){
		hclk = ROM_SYS_CLK;
	}
    SysTick->LOAD = u32Cnt * (hclk / 1000000);
    SysTick->VAL  = 0;                          // Clear counter
    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;  //disable systick
}

/**
 * @Param  : u32Cnt: delay time, max value:400ms
 */
static void udsf_hw_delay_ms(uint32_t u32Cnt)
{
	uint32_t hclk = 	XIP_SYS_CLK;

	if( p_rom_gb->boot_flag == ROM_STARTUP ){
		hclk = ROM_SYS_CLK;
	}
    uint32_t load_val;
    load_val = u32Cnt * (hclk / 1000);
    if (load_val <= 0xffffff)
        SysTick->LOAD = u32Cnt * (hclk / 1000);
    else
        SysTick->LOAD = 0xffffff;                //load max value
    SysTick->VAL  = 0;                           // Clear counter
    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
    while ((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
    SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk;   //disable systick
}

/* soft delay @20Mhz@ROMorSRAM*/
static void udsf_delay_us_xip(int us_cnt){
	for (int j = 0; j < us_cnt; j++)
	{
		for(int i = 0; i < 2; i++){
			if( i == 0 ){
				i++;
			}
		}
	}
}

/* soft delay @20Mhz@ROMorSRAM*/
static void udsf_delay_ms_xip( int ms_cnt){
	for (int j = 0; j < ms_cnt; j++)
	{
		udsf_delay_us_xip(1050);
	}
}

/* soft delay @20Mhz@BBSRAM*/
static void udsf_delay_us_bbsram_xip(int us_cnt){
	for (int j = 0; j < us_cnt; j++)
	{
		if( (j%2) == 0 ){
			j+=2;
		}


		//}
		//for(int i = 0; i < 1; i++){
//			if( i == 0 ){
//				i++;
//			}
		//}
	}
}

/* soft delay @20Mhz@BBSRAM*/
static void udsf_delay_ms_bbsram_xip( int ms_cnt){
	for (int j = 0; j < ms_cnt; j++)
	{
		udsf_delay_us_bbsram_xip(910);
	}
}


/* soft delay @40Mhz@ROMorSRAM*/
static void udsf_delay_us_rom(int us_cnt)
{
	for (int j = 0; j < us_cnt; j++)
	{
		for(int i = 0; i < 6; i++);
	}
}



/* soft delay @40Mhz@ROMorSRAM*/
static void udsf_delay_ms_rom( int ms_cnt){
	for (int j = 0; j < ms_cnt; j++)
	{
		udsf_delay_us_rom(976);
	}
}

/* soft delay @40Mhz@BBSRAM*/
static void udsf_delay_us_bbsram_rom(int us_cnt)
{
	for (int j = 0; j < us_cnt; j++)
	{
		if( j&0x80000000 ){
				j=0;
		}
	}
}



/* soft delay @40Mhz@ROMorSRAM*/
static void udsf_delay_ms_bbsram_rom( int ms_cnt){
	for (int j = 0; j < ms_cnt; j++)
	{
		udsf_delay_us_bbsram_rom(1024);
	}
}

static void udsf_slow_clk_delay1ms(void)
{
	for(uint8_t t=0; t<16; t++)
	{
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();//__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		//      __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		//      __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
	}
}

static void udsf_slow_clk_delay500us(void)
{
	for(uint8_t t=0; t<16; t++)
	{
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		__NOP();__NOP();__NOP();//__NOP();//__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		//__NOP();__NOP();//__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		//      __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
		//      __NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();__NOP();
	}
}

#if APPLICATION_MODE_ROM_START == APPLICATION_MODE
#define udsf_delay_us udsf_delay_us_rom
#define udsf_delay_ms udsf_delay_ms_rom
#define udsf_delay_us_bbsram udsf_delay_us_bbsram_rom
#define udsf_delay_ms_bbsram udsf_delay_ms_bbsram_rom
#else
#define udsf_delay_us udsf_delay_us_xip
#define udsf_delay_ms udsf_delay_ms_xip
#define udsf_delay_us_bbsram udsf_delay_us_bbsram_xip
#define udsf_delay_ms_bbsram udsf_delay_ms_bbsram_xip
#endif

#endif
